package uoc.tds.pec3.servidor;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NoSuchObjectException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.UnknownHostException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

import uoc.tds.pec3.comun.excepciones.ExcepcionGestorIncidencias;
import uoc.tds.pec3.comun.excepciones.ExcepcionRemota;

import uoc.tds.pec3.comun.interfaces.GestorIncidenciasInterface;
import uoc.tds.pec3.comun.utilidades.MensajesI18N;
import uoc.tds.pec3.servidor.bd.GestorBBDD;
import uoc.tds.pec3.servidor.implementacion.GestorIncidenciasImpl;

/**
 * Clase Servidor. Inicia y cierra el servidor RMI.
 * Conecta y desconecta con la base de datos.
 */
public class Servidor {

	private static Registry registro;
	private static GestorIncidenciasInterface objetoRemoto;

	/**
	 * Constructor de la clase Servidor
	 */
	public Servidor() {
		super();
	}

	/**
	 * Inicia el servidor RMI.
	 * @throws ExcepcionGestorIncidencias
	 * @throws ExcepcionRemota
	 */
	public static void inicio() throws ExcepcionGestorIncidencias, ExcepcionRemota {

		try {	
			registro = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);	
			objetoRemoto = new GestorIncidenciasImpl();
			Naming.rebind("rmi://localhost/GestorIncidencias",objetoRemoto);
			GestorBBDD.conectaBD();
		} catch (ExcepcionRemota e) { 
			try {
				// Elimina un posible objeto remoto RMI existente
				UnicastRemoteObject.unexportObject(registro, true);
			}catch (NoSuchObjectException ex) {
				throw new ExcepcionGestorIncidencias(
						MensajesI18N.getMensajeI18N("error.detencionServidor"),
						"(NoSuchObjectException)" + ex.getMessage());
			}
			throw e;
		} catch (UnknownHostException e) {
			throw new ExcepcionGestorIncidencias(
					MensajesI18N.getMensajeI18N("error.inicioServidor"),
					"(UnknownHostException)" + e.getMessage());
		} catch (RemoteException e) {
			throw new ExcepcionRemota(
					MensajesI18N.getMensajeI18N("error.inicioServidor"),
					"(RemoteException)" + e.getMessage());
		} catch (MalformedURLException e) {
			throw new ExcepcionGestorIncidencias(
					MensajesI18N.getMensajeI18N("error.inicioServidor"),
					"(MalformedURLException)" + e.getMessage());
		} catch (Exception e) {
			throw new ExcepcionGestorIncidencias(
					MensajesI18N.getMensajeI18N("error.inicioServidor"),
					"(Exception)" + e.getMessage());
		}
	}

	/*
	 * Cierra el servidor RMI.
	 * @throws ExcepcionGestorIncidencias
	 */
	public static void detencion() throws ExcepcionGestorIncidencias {
		try {
			String rmiObject[] = {};
			rmiObject = Naming.list("rmi://localhost");
			if (rmiObject.length > 0) {
				for (String element : rmiObject) {  
					Naming.unbind(element);
					break;
				}
			}
			UnicastRemoteObject.unexportObject(registro, true);
			GestorBBDD.desconectaBD();
		} catch (NotBoundException e) {
			throw new ExcepcionGestorIncidencias(
					MensajesI18N.getMensajeI18N("error.detencionServidor"),
					"(NotBoundException)" + e.getMessage());
		} catch (UnknownHostException e) {
			throw new ExcepcionGestorIncidencias(
					MensajesI18N.getMensajeI18N("error.detencionServidor"),
					"(UnknownHostException)" + e.getMessage());
		} catch (RemoteException e) {
			throw new ExcepcionGestorIncidencias(
					MensajesI18N.getMensajeI18N("error.detencionServidor"),
					"(RemoteException)" + e.getMessage());
		} catch (MalformedURLException e) {
			throw new ExcepcionGestorIncidencias(
					MensajesI18N.getMensajeI18N("error.detencionServidor"),
					"(MalformedURLException)" + e.getMessage());
		} catch (Exception e) {
			throw new ExcepcionGestorIncidencias(
					MensajesI18N.getMensajeI18N("error.detencionServidor"),
					"(Exception)" + e.getMessage());
		}

	}
}
